Updating VSCP firmware

Now that I have the code for the Mespelare module mostly working, it is time to update the VSCP firmware to the latest version. A few years have passed since Kurt has written the firmware for Hasselt (on which Mespelare is based), and the code is still using the old VSCP firmware. A few changes and bugfixes have been made in the meantime so it is time to upgrade.

Git pull

The first order of the day is to get the latest code from Github. You can either do a git pull from github.com/grodansparadis/vscp_firmware/, or download a zip file of the vscp_firmware repository. This repository will contain the following files & folders:

Make a backup of the existing code

Before we update our existing source code, it is wise to make a backup. To do this, open your project in MPLAB X, and right-click the project name in the project navigation tree (here my project is called Mespelare_v1.3). Now select Copy… from the menu.

Now give the project a new name. I’m using incremental version numbers so the new version will be Mespelare_v1.4.

Now close MPLAB X.

Update files

Now we’ll need to copy the newer files over the existing (old) files in our code folder. Find the folder /common and select the files vscp_firmware.c and vscp_firmware.h.

Copy them to the common folder under MPLAB project folder. Overwrite where necessary.

Now find the folder /PIC/common and select the files can18xx8.c, CAN18XX8.h, eeprom.c, eeprom.h and inttypes.h and copy them to the common folder under MPLAB project folder. Overwrite where necessary.

Build project

Now let’s fire up the new project in MPLAB X and see if it builds. For me it threw a few errors at the first go.

PIR2bits.EEIF in eeprom.c

The compiler stumbles over PIR2bits.EEIF in function writeEEPROM(), a register which is not defined for my PIC (18F45K80). Strangely enough the previous version of eeprom.c has a compiler pre-processor directive to account for the fact that some PICs define this register as PIR4bits.EEIF instead. So we’ll copy that bit of code in again.

...
#if defined(__18F25K80) || defined(__18F26K80) || defined(__18F45K80) || defined(__18F46K80) || defined(__18F65K80) || defined(__18F66K80)
	while (!PIR4bits.EEIF); // wait for interrupt to signal write complete
	PIR4bits.EEIF = 0; // clear EEPROM write operation interrupt flag
#else
	while (!PIR2bits.EEIF); // wait for interrupt to signal write complete
	PIR2bits.EEIF = 0; // clear EEPROM write operation interrupt flag
#endif ...

I opened a ticket for this issue so that this issue can be solved in a next version.

vscp_deviceURL[] declaration

The declaration for vscp_deviceURL[] seems to have changed from const far rom uint8_t to extern const uint8_t. I attempted to update that in main.c, but it throws a strange compiler error. So I just commented our the declaration in vscp_firmware.h and used it how it was in the older code in main.c.

readFPM() in eeprom.c

The function readFPM() seems to be missing from eeprom.c. I simply copied it in again from a previous version for now. Maybe I will come back to this later and see if the 2 calls to readFPM() in main.c can be handled using another function (like readEEPROM()).

////////////////////////////////////////////////////////////////////////////////
// Read Flash Program memory location using TBLREAD
////////////////////////////////////////////////////////////////////////////////
uint8_t readFPM( uint16_t address )
{
	uint8_t data;
		TBLPTRU = 0;    //limiting to 64K flash range
	TBLPTRH = ( address >> 8 ) & 0xff;
	TBLPTRL = address & 0xff; // Data Memory Address to read
	EECON1bits.EEPGD= 1; 	// set to read to program memory
	EECON1bits.CFGS = 0; 	// clear to read program memory
		_asm tblrd _endasm;
	data = TABLAT;
	return data;
}

vscp_omsg changes

The names of the variables vscp_omsg.class and vscp_omsg.type were changed to vscp_omsg.vscp_class and vscp_omsg.vscp_type.

struct _omsg {
	uint8_t flags; ///< Output message flags
	uint8_t priority; ///< Priority for the message 0-7
	uint16_t vscp_class; ///< VSCP class
	uint8_t vscp_type; ///< VSCP type
	/// Originating address is always *this* node
	uint8_t data[8]; ///< data bytes
};

struct _omsg vscp_omsg;

We’ll need to do a find-and-replace to change these names in all of our source code. The same goes for vscp_imsg. Annoying but easily fixed.

vscp_restoreDefaults in vscp_firmware.c

The function vscp_restoreDefaults() seems to be

  • declared in vscp_firmware.h (void vscp_restoreDefaults(void);)
  • used in vscp_firmware.c (in vscp_writeStdReg())
  • but implemented nowhere.

MPLAB X crashes on it in the linking stage. The same goes for the functions vscp_getFamilyType() and vscp_getFamilyCode()

Upon submitting a ticket, Ake let me know that these functions are not yet used so they are not implemented. I implemented them as empty functions in vscp_firmware.c.

//not yet used in the protocol spec (see 
//https://github.com/grodansparadis/vscp_firmware/issues/3
//http://www.vscp.org/docs/vscpspec/doku.php?id=register_abstraction_model register 162
uint32_t vscp_getFamilyCode(void) {
	return 0;
}

uint32_t vscp_getFamilyType(void) {
	return 0;
}

section ‘.stringtable’ can not fit the section

And then the PIC maxed out its memory. This means we’ll need to switch the memory model from small code model to large code model. This is done in the project options, categories Conf: [default], C18 (Global Options), mcc18, and then selecting Memory Model from the option categories.

After that it is a good idea to do a ‘Clean and build’ to get rid of older object files which might still be using the small memory model and conflict.

And then I get the error

Error - section '.code_fxd1616u.o' can not fit the section. Section '.code_fxd1616u.o' length=0x0000002c

I have no idea what that is about. End of exercise for me. I think I’ll upgrade my compiler to XC8 first.

Resources

Comments